package com.jueban.serviceImpl;

import com.jueban.Dto.*;
import com.jueban.Vo.ResultVo;
import com.jueban.Vo.UserVo;
import com.jueban.Vo.UsersVo;
import com.jueban.model.user.User;
import com.jueban.repository.StudentRepository;
import com.jueban.repository.UserRepository;
import com.jueban.service.UserService;
import com.jueban.util.Enum.JobType;
import com.jueban.util.Enum.UserType;
import com.jueban.util.Messages;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    private final StudentRepository studentRepository;

    //private final TeacherRepository teacherRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository, StudentRepository studentRepository) {
        this.userRepository = userRepository;
        this.studentRepository = studentRepository;
        //this.teacherRepository = teacherRepository;
    }


    @Override
    public User getUser() {
        return userRepository.findByUsername(getUsername());
    }

    @Override
    public User getUserByUsername(String username) {
        return userRepository.findByUsername(username);

        /*
        UserType type = userRepository.findByUsername(username).getUserType();
        switch (type) {
            case admin:
                return userRepository.findByUsername(username);
            case student:
                return studentRepository.findByUsername(username);
            case teacher:
                return teacherRepository.findByUsername(username);
            default:
                return userRepository.findByUsername(username);
        }*/
    }

    @Override
    public ResultVo hasUsername(String username) {
        User user = userRepository.findByUsername(username);
        ResultVo resultVo = new ResultVo();
        if (user != null) {
            resultVo.setSucceeded();
            resultVo.setMessages(Messages.USERNAME_ALREADY_EXIST);
        } else {
            resultVo.setFailed();
            resultVo.setMessages(Messages.USERNAME_CAN_USE);
        }
        return resultVo;
    }

    //分类储存
    @Override
    public ResultVo register(UserDto userDto) {
        User user = new User();
        ResultVo resultVo = new ResultVo();
        userDto.infoUser(user);
        user.setIsRegistered(true);
        if (userRepository.findByUsername(user.getUsername()) == null) {
            userRepository.save(user);
            if (user.getId() != null) {
                resultVo.setSucceeded();
                resultVo.setMessages(Messages.USER_REGISTER_SUCCEED);
            } else {
                resultVo.setFailed();
                resultVo.setMessages(Messages.USER_REGISTER_FAIL);
            }
        } else {
            resultVo.setFailed();
            resultVo.setMessages(Messages.USERNAME_ALREADY_EXIST);
        }
        return resultVo;
    }

    @Override
    public ResultVo resetPassword(ResetPasswordDto resetPasswordDto) {
        ResultVo resultVo = new ResultVo();
        User user = getUser();
        if (user == null) {
            return isNoLogin();
        }
        if (user.isPassword(resetPasswordDto.getOldPassword())) {
            user.setPassword(resetPasswordDto.getNewPassword());

            try {
                userRepository.save(user);
                resultVo.setMessages(Messages.RESET_PASSWORD_SUCCEED);
                resultVo.setSucceeded();
            } catch (Exception e) {
                e.printStackTrace();
                resultVo.setFailed();
                resultVo.setMessages(Messages.RESET_PASSWORD_FAIL);
            }
        } else {
            resultVo.setMessages(Messages.OLD_PASSWORD_ERROR);
            resultVo.setFailed();
        }
        return resultVo;
    }

    @Override
    public ResultVo changeInfo(UserDto userDto) {
        ResultVo resultVo = new ResultVo();
        User user = getUser();
        if (user == null) {
            return isNoLogin();
        }
        userDto.infoTransfer(user);
        try {
            userRepository.save(user);
            resultVo.setSucceeded();
            resultVo.setMessages(Messages.USER_INFO_CHANGED);
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setFailed();
            resultVo.setMessages(Messages.USER_INFO_CHANGE_FAIL);
        }
        return resultVo;
    }

    @Override
    public ResultVo changeJob(JobTypeDto jobTypeDto) {
        ResultVo resultVo = new ResultVo();

        User user = userRepository.findOne(jobTypeDto.getId());
        if(user != null){
            if(user.getUserType().equals(UserType.teacher)){
                user.setJobType(JobType.valueOf(jobTypeDto.getJobType()));
                userRepository.save(user);
                resultVo.setSucceeded();
                resultVo.setMessages(Messages.JOB_CHANGE_SUCCEED);
                return resultVo;
            }
        }
        resultVo.setFailed();
        resultVo.setMessages(Messages.JOB_CHANGE_FAIL);
        return resultVo;


    }

    @Override
    public ResultVo setRegister(RegisterDto registerDto) {
        ResultVo resultVo = new ResultVo();
        User user = userRepository.findOne(registerDto.getId());
        if (user != null) {
            user.setIsRegistered(registerDto.getIsRegister());
            userRepository.save(user);
            resultVo.setSucceeded();
            resultVo.setMessages(Messages.SET_REGISTERED_SUCCEED);
        } else {
            resultVo.setFailed();
            resultVo.setMessages(Messages.SET_REGISTERED_FAIL);
        }
        return resultVo;
    }

    @Override
    public UsersVo getUnregister(UnregisteredUserQueryDto pageDto) {
        Pageable pageable = new PageRequest(pageDto.getOffset(), pageDto.getPageSize());
        UsersVo resultVo = new UsersVo();
        try {
            Page<User> users = userRepository.findAllByNameIsLikeAndIsRegistered(pageable
                    , "%" + pageDto.getName() + "%", false);
            resultVo.setProperties(users);
            resultVo.setSucceeded();
            resultVo.setMessages(Messages.GET_UNRIGISTER_ACCOUNT_SUCCEED);
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setFailed();
            resultVo.setMessages(Messages.GET_UNRIGISTER_ACCOUNT_FAIL);
        }
        return resultVo;
    }

    @Override
    @PreAuthorize(value = "isAuthenticated()")
    public UserVo getInfo() {
        User user = getUser();
        return new UserVo(getUser());
    }

    //不修改密码的前提下修改用户信息
    public ResultVo updateUserNotPassword(UserDto userDto)
    {
        ResultVo resultVo = new ResultVo();
        try
        {
            User userOld = userRepository.findOne(userDto.getId());
            userDto.infoUserNotPassword(userOld);
            userRepository.save(userOld);
            resultVo.setMessages(Messages.USER_INFO_CHANGED);
        }catch (Exception e)
        {
            resultVo.setMessages(Messages.USER_INFO_CHANGE_FAIL);
        }
        return resultVo;
    }
    //修改用户信息，包括密码
    public ResultVo updateUser(UserDto userDto)
    {
        ResultVo resultVo = new ResultVo();
        try
        {
            User userOld = userRepository.findOne(userDto.getId());
            userDto.infoUser(userOld);
            userRepository.save(userOld);
            resultVo.setMessages(Messages.USER_INFO_CHANGED);
        }catch (Exception e)
        {
            resultVo.setMessages(Messages.USER_INFO_CHANGE_FAIL);
        }
        return resultVo;
    }

    //根据传入条件分页查询所有用户
    @Override
    public UsersVo findAllUser(UserQueryDto userQueryDto)
    {
        Sort sort = new Sort("department");
        Pageable pageable = new PageRequest(userQueryDto.getOffset(), userQueryDto.getPageSize(), sort);
        Page<User> users = userRepository.findAllByDepartmentAndUsernameAndName(pageable, userQueryDto.getDepartment(), userQueryDto.getUsername(), userQueryDto.getName());
        UsersVo usersVo = new UsersVo();
        usersVo.setProperties(users);
        return usersVo;
    }

    private ResultVo isNoLogin() {
        ResultVo resultVo = new ResultVo();
        resultVo.setFailed();
        resultVo.setMessages(Messages.IS_NO_LOGIN);
        return resultVo;
    }

    private String getUsername() {
        String username = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof String) {
            username = (String) principal;
        } else if (principal instanceof org.springframework.security.core.userdetails.User) {
            username = ((org.springframework.security.core.userdetails.User) principal).getUsername();
        }
        return username;
    }
}

        /*
        Teacher teacher = teacherRepository.findOne(jobTypeDto.getId());
        if (teacher != null) {
            teacher.setJobType(JobType.valueOf(jobTypeDto.getJobType()));
            teacherRepository.save(teacher);
            resultVo.setSucceeded();
            resultVo.setMessages(Messages.JOB_CHANGE_SUCCEED);
        } else {
            resultVo.setFailed();
            resultVo.setMessages(Messages.JOB_CHANGE_FAIL);
        }
        return resultVo;
        */
